package cool.mtc.web.annotation.serializer.dict;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import cool.mtc.core.util.StringUtil;
import cool.mtc.web.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/**
 * @author 明河
 * 字典数据序列化类
 */
@Slf4j
public class DictSerializer extends StdSerializer<Object> implements ContextualSerializer {
    private String type;
    private String valueFieldName;

    public DictSerializer() {
        super(Object.class);
    }

    public DictSerializer(String type, String valueFieldName) {
        super(Object.class);
        this.type = type;
        this.valueFieldName = valueFieldName;
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) {
        Dict annotation = property.getAnnotation(Dict.class);
        return new DictSerializer(annotation.type(), annotation.valueFieldName());
    }

    @Override
    public void serialize(Object key, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // 原字段值
        gen.writeObject(key);

        // 翻译的字典value值
        String valueFieldName;
        if (StringUtil.isEmpty(this.valueFieldName)) {
            String keyFieldName = gen.getOutputContext().getCurrentName();
            String valueFieldNameSuffix = "Name";
            if (keyFieldName.endsWith("Id")) {
                valueFieldName = keyFieldName.substring(0, keyFieldName.length() - 2) + valueFieldNameSuffix;
            } else {
                valueFieldName = keyFieldName + valueFieldNameSuffix;
            }
        } else {
            valueFieldName = this.valueFieldName;
        }

        // 取出字典的value值
        DictSerializerService service = SpringUtil.getBean(DictSerializerService.class);
        Object value = service.getValueByTypeAndKey(this.type, key);
        gen.writeObjectField(valueFieldName, value);
    }
}
